CS245 Programming Languages

Douglas Blank

Bryn Mawr College, Fall 2014

On the first exam, I asked you to write the function list-of that takes a function $f$, and returns a function that takes a list. The returned function should return #t if every item in the list has (f item) as #t.

It would work like this:

In  [1]: ((list-of number?) '(1 2 3 4))
Out [1]: #t

Here is one possible answer:

In [ ]:
(define list-of
  (lambda (f)
    (lambda (ls)
      (cond
       ((null? ls) #t)
       ((f (car ls)) ((list-of f) (cdr ls)))
       (else #f)))))

That is a simple implementation of the definition. But it does recreate the function that takes the list each time it needs it, because the function (list-of f) doesn't have a name.

Here is a version that uses letrec (let allowing recursive definitions), so that you only define that function once, and give it a name:

In [2]:
(define list-of
  (lambda (f)
    (letrec ((list-of-f
              (lambda (ls)
                (cond
                 ((null? ls) #t)
                 ((not (f (car ls))) #f)
                 (else (list-of-f (cdr ls)))))))
     list-of-f)))

That version is a bit verbose, but also gets the job done.

Finally, here is a version that uses the "named let" construct in Scheme:

In [3]:
(define list-of
  (lambda (f)
    (lambda (ls)
      (let loop ((ls ls))
        (cond
         ((null? ls) #t)
         ((not (f (car ls))) #f)
         (else (loop (cdr ls))))))))

Ah, yes. That is short, and beautiful.

Which do you prefer? Do they all give the same answers? Are there pros and cons to each?